package net.gdface.sdk.thrift;
import java.nio.ByteBuffer;
import net.gdface.image.ImageErrorException;
import net.gdface.sdk.CodeInfo;
import net.gdface.sdk.FRect;
import net.gdface.sdk.FaceApi;
import net.gdface.sdk.NotFaceDetectedException;
import net.gdface.thrift.TypeTransformer;
import net.gdface.thrift.exception.client.BaseServiceRuntimeException;
import net.gdface.thrift.ClientFactory;

import com.facebook.swift.service.RuntimeTApplicationException;
/**
 * decorator pattern 装饰者模式实现{@link FaceApi}的远程调用接口<br>
 * 转发所有{@link FaceApi}接口方法到{@link #delegate()}指定的实例<br>
 * 所有服务端抛出的{@link RuntimeException}异常被封装到{@link ServiceRuntimeException}中抛出<br>
 * 建议使用{@link FaceApiClientFactory}工厂类创建 FaceApiThriftClientDecorator 实例<br>
 * 计算机生成代码(generated by automated tools ThriftServiceDecoratorGenerator @author guyadong)<br>
 * @author guyadong
 *
 */
public class FaceApiThriftClientDecorator implements FaceApi {
    private final net.gdface.sdk.thrift.client.FaceApi delegate;
    
    public FaceApiThriftClientDecorator(net.gdface.sdk.thrift.client.FaceApi delegate) {
        super();
        if(null == delegate){
            throw new NullPointerException("delegate is null");
        }
        this.delegate = delegate;
    }

    /**
     * 返回被装饰的{@link net.gdface.sdk.thrift.client.FaceApi}实例
     * @return
     */
    public net.gdface.sdk.thrift.client.FaceApi delegate() {
        return delegate;
    }
    /**
     * 服务端抛出的 runtime 异常
     * @author guyadong
     *
     */
    public class ServiceRuntimeException extends BaseServiceRuntimeException{
        private static final long serialVersionUID = 1L;

        private ServiceRuntimeException(net.gdface.sdk.thrift.client.ServiceRuntimeException cause) {
            super(cause);
            type = cause.getType();
            message = cause.getMessage();
            causeClass = cause.getCauseClass();
            causeFields = cause.getCauseFields();
            serviceStackTraceMessage = cause.getServiceStackTraceMessage();
        }        
    }
    /**
     * 创建client接口实例工厂类
     */
    public static class FaceApiClientFactory extends ClientFactory{
        public static final FaceApiClientFactory builder(){
            return new FaceApiClientFactory();
        }
        /** get synchronized instance of {@link FaceApi} */ 
        public FaceApiThriftClientDecorator build(){
            return build(
            		net.gdface.sdk.thrift.client.FaceApi.class,
            		FaceApiThriftClientDecorator.class);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#compare2Face(byte[],net.gdface.sdk.CodeInfo,byte[],net.gdface.sdk.CodeInfo)}
     */
    @Override
    public double compare2Face(byte[] imgData1,
        CodeInfo facePos1,
        byte[] imgData2,
        CodeInfo facePos2) 
        throws ImageErrorException,NotFaceDetectedException{
        try{
            return delegate().compare2Face(imgData1,
                TypeTransformer.getInstance().to(
                    facePos1,
                    CodeInfo.class,
                    net.gdface.sdk.thrift.client.CodeInfo.class),
                imgData2,
                TypeTransformer.getInstance().to(
                    facePos2,
                    CodeInfo.class,
                    net.gdface.sdk.thrift.client.CodeInfo.class));
        }
        catch(net.gdface.sdk.thrift.client.ImageErrorException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.ImageErrorException.class,
                    ImageErrorException.class);
        }
        catch(net.gdface.sdk.thrift.client.NotFaceDetectedException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.NotFaceDetectedException.class,
                    NotFaceDetectedException.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#compareCode(byte[],byte[])}
     */
    @Override
    public double compareCode(byte[] code1,
        byte[] code2) 
        {
        try{
            return delegate().compareCode(code1,
                code2);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#detectAndCompare2Face(byte[],net.gdface.sdk.FRect,byte[],net.gdface.sdk.FRect)}
     */
    @Override
    public double detectAndCompare2Face(byte[] imgData1,
        FRect detectRect1,
        byte[] imgData2,
        FRect detectRect2) 
        throws ImageErrorException,NotFaceDetectedException{
        try{
            return delegate().detectAndCompare2Face(imgData1,
                TypeTransformer.getInstance().to(
                    detectRect1,
                    FRect.class,
                    net.gdface.sdk.thrift.client.FRect.class),
                imgData2,
                TypeTransformer.getInstance().to(
                    detectRect2,
                    FRect.class,
                    net.gdface.sdk.thrift.client.FRect.class));
        }
        catch(net.gdface.sdk.thrift.client.ImageErrorException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.ImageErrorException.class,
                    ImageErrorException.class);
        }
        catch(net.gdface.sdk.thrift.client.NotFaceDetectedException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.NotFaceDetectedException.class,
                    NotFaceDetectedException.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#detectAndGetCodeInfo(byte[],int,net.gdface.sdk.FRect)}
     */
    @Override
    public CodeInfo[] detectAndGetCodeInfo(byte[] imgData,
        int faceNum,
        FRect detectRectangle) 
        throws ImageErrorException,NotFaceDetectedException{
        try{
            return TypeTransformer.getInstance().toArray(
                    delegate().detectAndGetCodeInfo(imgData,
                faceNum,
                TypeTransformer.getInstance().to(
                    detectRectangle,
                    FRect.class,
                    net.gdface.sdk.thrift.client.FRect.class)),
                    net.gdface.sdk.thrift.client.CodeInfo.class,
                    CodeInfo.class);
        }
        catch(net.gdface.sdk.thrift.client.ImageErrorException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.ImageErrorException.class,
                    ImageErrorException.class);
        }
        catch(net.gdface.sdk.thrift.client.NotFaceDetectedException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.NotFaceDetectedException.class,
                    NotFaceDetectedException.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
        catch(RuntimeTApplicationException e){
            return net.gdface.thrift.ThriftUtils.returnNull(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#detectFace(byte[],net.gdface.sdk.FRect)}
     */
    @Override
    public CodeInfo[] detectFace(byte[] imgData,
        FRect detectRectangle) 
        throws ImageErrorException{
        try{
            return TypeTransformer.getInstance().toArray(
                    delegate().detectFace(imgData,
                TypeTransformer.getInstance().to(
                    detectRectangle,
                    FRect.class,
                    net.gdface.sdk.thrift.client.FRect.class)),
                    net.gdface.sdk.thrift.client.CodeInfo.class,
                    CodeInfo.class);
        }
        catch(net.gdface.sdk.thrift.client.ImageErrorException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.ImageErrorException.class,
                    ImageErrorException.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
        catch(RuntimeTApplicationException e){
            return net.gdface.thrift.ThriftUtils.returnNull(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#detectFaceAgain(byte[],net.gdface.sdk.FRect[])}
     */
    @Override
    public CodeInfo[] detectFaceAgain(byte[] imgData,
        FRect[] detectRects) 
        {
        try{
            return TypeTransformer.getInstance().toArray(
                    delegate().detectFaceAgain(imgData,
                TypeTransformer.getInstance().to(
                    detectRects,
                    FRect.class,
                    net.gdface.sdk.thrift.client.FRect.class)),
                    net.gdface.sdk.thrift.client.CodeInfo.class,
                    CodeInfo.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
        catch(RuntimeTApplicationException e){
            return net.gdface.thrift.ThriftUtils.returnNull(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#getCodeInfo(byte[],int,net.gdface.sdk.CodeInfo[])}
     */
    @Override
    public CodeInfo[] getCodeInfo(byte[] imgData,
        int faceNum,
        CodeInfo[] facePos) 
        throws NotFaceDetectedException{
        try{
            return TypeTransformer.getInstance().toArray(
                    delegate().getCodeInfo(imgData,
                faceNum,
                TypeTransformer.getInstance().to(
                    facePos,
                    CodeInfo.class,
                    net.gdface.sdk.thrift.client.CodeInfo.class)),
                    net.gdface.sdk.thrift.client.CodeInfo.class,
                    CodeInfo.class);
        }
        catch(net.gdface.sdk.thrift.client.NotFaceDetectedException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.NotFaceDetectedException.class,
                    NotFaceDetectedException.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
        catch(RuntimeTApplicationException e){
            return net.gdface.thrift.ThriftUtils.returnNull(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#hasFace(byte[],net.gdface.sdk.FRect)}
     */
    @Override
    public boolean hasFace(byte[] imgData,
        FRect detectRectangle) 
        throws ImageErrorException{
        try{
            return delegate().hasFace(imgData,
                TypeTransformer.getInstance().to(
                    detectRectangle,
                    FRect.class,
                    net.gdface.sdk.thrift.client.FRect.class));
        }
        catch(net.gdface.sdk.thrift.client.ImageErrorException e){
            throw TypeTransformer.getInstance().to(
                    e,
                    net.gdface.sdk.thrift.client.ImageErrorException.class,
                    ImageErrorException.class);
        }
        catch(net.gdface.sdk.thrift.client.ServiceRuntimeException e){
            throw new ServiceRuntimeException(e);
        }
    }
    /**
     * @see {@link net.gdface.sdk.FaceApi#isLocal()}
     */
    @Override
    public boolean isLocal(){
        return false;
    }
}